package com.sls.core.util;

import java.io.File;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.log4j.Logger;

import com.sls.core.http.HttpClient;
import com.sls.core.socket.ServerDisponseException;
import com.sls.game.assist.Helper;
import com.sls.game.constant.ExceptionCodeDes;
import com.sls.game.dao.DownstreamUserDAO;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.GoodsOrderLogDAO;
import com.sls.game.parser.ohfei.OhFeiServerSaxParseXml;
import com.sls.game.parser.sls.OrderStatusSendParse;
import com.sls.game.pojo.DownstreamUserInfo;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.GoodsOrderLog;
import com.sls.game.pojo.OhFeiServerInfo;
import com.sls.game.pojo.SLSHttpInterfaceInfo;

/**
 * 
 * @description 订单结果异步定时发送给下游用户
 * @author Wangxuegang
 * @date 2013-1-31
 */
public class TimerSendDownUserMsg {

	private static Logger log = Logger.getLogger(TimerSendDownUserMsg.class);

	@Resource(name = "goodsOrderDAO")
	private GoodsOrderDAO goodsOrderDAO;

	@Resource(name = "downstreamUserDAO")
	private DownstreamUserDAO downstreamUserDAO;

	@Resource(name = "goodsOrderLogDAO")
	private GoodsOrderLogDAO goodsOrderLogDAO;

	private HttpClient httpClient = new HttpClient();

	/**
	 * 
	 */
	public void saveSendOrderStatusMsg() {
		log.info("定时扫描开始...");
		// 殴飞订单结果定时查询
		// queryOhFeiInHandle();

		String synOrAsy = "1";
		List<GoodsOrderInfo> list = null;
		list = goodsOrderDAO.queryGoodsOrderInfoList(synOrAsy);
		if (list != null && list.size() > 0) {
			for (GoodsOrderInfo info : list) {
				// 订单号
				String orderId = info.getOrderId();
				// 下游用户编号
				String contractId = info.getContractId();
				// 下游用户密钥
				String secretKey = null;
				DownstreamUserInfo downstreamUserInfo = null;
				downstreamUserInfo = downstreamUserDAO
						.queryUserByUserNO(contractId);
				if (downstreamUserInfo != null) {
					secretKey = downstreamUserInfo.getSecretKey();
				}

				sendHttpMsg(info, orderId, secretKey);
			}
		}
	}

	/**
	 * 殴飞订单结果定时查询<br>
	 * 根据上游供应商编号、支付状态成功、订单状态处理中查询相关记录
	 * 
	 * @date 2013-03-22
	 */
	@SuppressWarnings("unused")
	private void queryOhFeiInHandle() {
		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setIsPay("1"); // 支付成功
		goodsOrderInfo.setSupplyId("20121000"); // 殴飞
		goodsOrderInfo.setStatus("2"); // 处理中
		List<GoodsOrderInfo> list = null;
		list = goodsOrderDAO.queryOrderBySomeConditions(goodsOrderInfo);
		if (list != null && list.size() > 0) {
			for (GoodsOrderInfo info : list) {
				// 订单号
				String orderId = info.getOrderId();

				// SP编码如（A00001）在登陆系统时得到以A开头的编号
				String userid = "";
				// 订单查询地址
				String statusQueryAddress = "";
				// 从xml配置文件中读取访问地址
				List<OhFeiServerInfo> serverList = OhFeiServerSaxParseXml
						.parseXmlString("conf" + File.separator
								+ "ohFeiServer.xml");
				if (serverList.size() > 0) {
					for (OhFeiServerInfo ohFeiServerInfo : serverList) {
						userid = ohFeiServerInfo.getUserid().trim();
						statusQueryAddress = ohFeiServerInfo
								.getStatusQueryAddress().trim();
					}
				}

				String statusRes = sendOrderQueryMsg(orderId, userid,
						statusQueryAddress);

				if ("1".equals(statusRes)) { // 成功
					// 订单处理结果
					String status = "1";
					updateGoodsorder(status, orderId);
				}
			}
		}
	}

	/**
	 * 根据交易返回的结果更新订单表
	 * 
	 * @param status
	 * @param orderId
	 */
	private void updateGoodsorder(String status, String orderId) {
		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setStatus(status);
		goodsOrderInfo.setOrderId(orderId);
		goodsOrderInfo.setSynOrAsy("1"); // 默认异步通知

		String nowTime = ServerDateAndTime.getNowDateTime();
		goodsOrderInfo.setSupOrderSuccessTime(nowTime);
		// 数据更新
		try {
			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}

		// 写订单日志
		try {
			String orderId1 = orderId;
			GoodsOrderInfo goodsOrderInfo1 = new GoodsOrderInfo();
			goodsOrderInfo1 = this.goodsOrderDAO.queryByOrderId(orderId1);
			if (goodsOrderInfo1 != null) {
				GoodsOrderLog orderLog = Helper.copy(goodsOrderInfo1);
				orderLog.setId(UUID.randomUUID().toString());
				orderLog.setModifyTime(ServerDateAndTime
						.getNowDateTimeOfFormat());
				this.goodsOrderLogDAO.insert(orderLog);
			}

		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
	}

	/**
	 * 发http请求，查询殴飞订单状态值
	 * 
	 * @param orderId
	 * @param userid
	 * @param statusQueryAddress
	 * @return
	 */
	private String sendOrderQueryMsg(String orderId, String userid,
			String statusQueryAddress) {
		String result = null;
		StringBuilder strBui = new StringBuilder();
		strBui.append("http://");
		strBui.append(statusQueryAddress);
		strBui.append("?");
		strBui.append("userid=");
		strBui.append(userid);
		strBui.append("&");
		strBui.append("spbillid=");
		strBui.append(orderId);

		String url = strBui.toString().trim();
		HttpClient httpClient = new HttpClient();
		try {
			// 供应商返回消息编码方式
			String supplyEncode = "GB2312";
			String resStr = httpClient.doGet(url, supplyEncode);
			result = resStr.trim();
		} catch (Exception e) {
			log.error("殴飞订单查询出现异常！", e);
			throw new ServerDisponseException(
					ExceptionCodeDes.HTTP_URL_FAILED.getCode(),
					ExceptionCodeDes.HTTP_URL_FAILED.getDescription());
		}

		return result;
	}

	// public static void main(String[] args){
	// TimerSendDownUserMsg msg = new TimerSendDownUserMsg();
	// String str = msg.sendOrderQueryMsg("2013032200000221", "A102177",
	// "202.102.53.141:83/api/query.do");
	// System.out.println(str);
	// }

	/**
	 * 给下游用户发送订单结果
	 * 
	 * @param info
	 * @param orderId
	 * @param secretKey
	 */
	private void sendHttpMsg(GoodsOrderInfo info, String orderId,
			String secretKey) {
		// 回调地址
		String notifyUrl = info.getNotifyUrl();
		// 合作方订单编号
		String ptOrderNo = info.getMerchantOrderId();
		// 手拉手订单编号
		String supOrderNo = orderId;
		// 订单处理结果
		String status = info.getStatus();
		if ("1".equals(status)) { // 成功
			status = "ORDER_SUCCESS";
		} else if ("0".equals(status)) { // 失败
			status = "ORDER_FAILED";
		}

		// 手拉手充值成功时间
		String supOrderSuccessTime = info.getSupOrderSuccessTime();
		// 下游回调失败次数
		String failureNum = info.getfailureNum();
		if (failureNum != null && !("".equals(failureNum))) {
			int failureNumVal = Integer.parseInt(failureNum);
			if (failureNumVal < 3) {
				sendHttpAboutMsg(ptOrderNo, supOrderNo, status,
						supOrderSuccessTime, secretKey, notifyUrl, orderId,
						failureNum);
			} else { // ---------失败次数超过3次,不再主动通知下游结果
				dealAsynResResult(null, orderId, failureNum);
			}
		} else {
			sendHttpAboutMsg(ptOrderNo, supOrderNo, status,
					supOrderSuccessTime, secretKey, notifyUrl, orderId,
					failureNum);
		}

	}

	/**
	 * 发送http请求
	 * 
	 * @param ptOrderNo
	 * @param supOrderNo
	 * @param status
	 * @param supOrderSuccessTime
	 * @param secretKey
	 * @param notifyUrl
	 * @param orderId
	 * @param failureNum
	 */
	private void sendHttpAboutMsg(String ptOrderNo, String supOrderNo,
			String status, String supOrderSuccessTime, String secretKey,
			String notifyUrl, String orderId, String failureNum) {
		String para = createParameter(ptOrderNo, supOrderNo, status,
				supOrderSuccessTime, secretKey);
		String httpUrl = notifyUrl + "?" + para;

		// 供应商返回消息编码方式
		String supplyEncode = "UTF-8";
		try {
//			log.info("定时异步通知下游订单最终结果内容：" + "\n合作方订单编号：" + ptOrderNo
//					+ "\n本地订单编号:" + supOrderNo + "\n订单处理结果:" + status
//					+ "\n本地充值成功时间:" + supOrderSuccessTime);
			log.info("定时异步通知url：  " + httpUrl);

			// 给下游发消息
			String xmlStr = httpClient.doGet(httpUrl, supplyEncode);
			dealAsynResResult(xmlStr, orderId, failureNum);
		} catch (Exception e) {
			dealAsynResResult(null, orderId, failureNum);
			log.error(e);
		}
	}

	/**
	 * 更新异步通知状态
	 * 
	 * @param xmlStr
	 * @param orderId
	 */
	private void dealAsynResResult(String xmlStr, String orderId,
			String failureNum) {
		String handleResult = null;
		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		if (xmlStr != null && !("".equals(xmlStr))) {
			SLSHttpInterfaceInfo slsInfo = null;
			slsInfo = OrderStatusSendParse.readUserSendMsg(xmlStr);
			log.info("下游异步通知响应的内容：" + xmlStr);
			
//			log.info("下游异步通知响应的内容：" + "\n处理结果：" + slsInfo.getHandleResult()
//					+ "\n失败码:" + slsInfo.getFailedCode() + "\n失败原因："
//					+ slsInfo.getFailedReason());
			
			if (slsInfo != null) {
				handleResult = slsInfo.getHandleResult();
			}

			if (!("SUCCESS".equals(handleResult))) { // 异步回调失败
				if (failureNum == null || "".equals(failureNum)) {
					failureNum = "0";
					goodsOrderInfo.setfailureNum(failureNum);
				} else {
					int failureNumVal = Integer.parseInt(failureNum) + 1;
					String failureNumStr = failureNumVal + "";
					goodsOrderInfo.setfailureNum(failureNumStr);
				}
			} else {
				String failureNumStr = "0";
				goodsOrderInfo.setfailureNum(failureNumStr);
			}
		} else {
			handleResult = "SUCCESS";
		}

		goodsOrderInfo.setOrderId(orderId);
		goodsOrderInfo.setUserhandleResult(handleResult);
		// 数据更新
		try {
			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
		// 写订单日志
		try {
			GoodsOrderInfo goodsOrderInfo1 = new GoodsOrderInfo();
			goodsOrderInfo1 = this.goodsOrderDAO.queryByOrderId(orderId);
			if (goodsOrderInfo1 != null) {
				GoodsOrderLog orderLog = Helper.copy(goodsOrderInfo1);
				orderLog.setId(UUID.randomUUID().toString());
				orderLog.setModifyTime(ServerDateAndTime
						.getNowDateTimeOfFormat());
				goodsOrderLogDAO.insert(orderLog);
			}

		} catch (Exception e) {
			log.error(e.toString());
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}

	}

	/**
	 * 拼装异步通知参数
	 * 
	 * @param ptOrderNo
	 * @param supOrderNo
	 * @param status
	 * @param supOrderSuccessTime
	 * @return
	 */
	private String createParameter(String ptOrderNo, String supOrderNo,
			String status, String supOrderSuccessTime, String secretKey) {
		String para = null;
		String sign = createOfSign(ptOrderNo, supOrderNo, status,
				supOrderSuccessTime, secretKey);
		StringBuilder strBui = new StringBuilder();
		strBui.append("ptOrderNo=");
		strBui.append(ptOrderNo);
		strBui.append("&");
		strBui.append("supOrderNo=");
		strBui.append(supOrderNo);
		strBui.append("&");
		strBui.append("status=");
		strBui.append(status);

		if ("1".equals(status)) { // 成功
			strBui.append("&");
			strBui.append("supOrderSuccessTime=");
			strBui.append(supOrderSuccessTime);
		} else if ("0".equals(status)) { // 失败
			strBui.append("&");
			strBui.append("failedCode=");
			strBui.append("208");
		}
		strBui.append("&");
		strBui.append("sign=");
		strBui.append(sign);

		para = strBui.toString().trim();
		return para;
	}

	/**
	 * 生成签名字符串
	 */
	private String createOfSign(String ptOrderNo, String supOrderNo,
			String status, String supOrderSuccessTime, String secretKey) {
		StringBuilder strBui = new StringBuilder();
		strBui.append(ptOrderNo);
		strBui.append(supOrderNo);
		strBui.append(status);

		if ("1".equals(status)) { // 成功
			strBui.append(supOrderSuccessTime);
		} else if ("0".equals(status)) { // 失败
			strBui.append("208");
		}
		strBui.append(secretKey);

		String data = strBui.toString().trim();
		String sign = UtilMD5Encryption.createMD5Encryption(data);

		return sign;
	}

}
